<template>
  <div class="work-tree">
    <div class="canvas-container" ref="container"></div>
    <div class="controls">
      <el-button @click="autoRotate = !autoRotate">
        {{ autoRotate ? '停止旋转' : '自动旋转' }}
      </el-button>
    </div>
    
    <!-- 图片预览对话框 -->
    <el-dialog
      v-model="previewVisible"
      :title="currentImage.name"
      width="90%"
      class="preview-dialog"
      :before-close="handleClosePreview"
      fullscreen>
      <div class="preview-container">
        <div class="preview-toolbar">
          <el-button-group>
            <el-button @click="handleZoomIn" icon="el-icon-zoom-in">放大</el-button>
            <el-button @click="handleZoomOut" icon="el-icon-zoom-out">缩小</el-button>
          </el-button-group>
          <el-button-group>
            <el-button @click="handleRotateLeft" icon="el-icon-refresh-left">向左旋转</el-button>
            <el-button @click="handleRotateRight" icon="el-icon-refresh-right">向右旋转</el-button>
          </el-button-group>
          <el-button @click="handleReset" icon="el-icon-refresh">重置</el-button>
        </div>
        <div class="preview-wrapper" 
             @wheel="handleWheel"
             @mousedown="handleMouseDown"
             @mousemove="handleMouseMove"
             @mouseup="handleMouseUp"
             @mouseleave="handleMouseUp">
          <img 
            :src="currentImage.url" 
            class="preview-image"
            :style="{
              transform: `translate(${translateX}px, ${translateY}px) scale(${scale}) rotate(${rotation}deg)`,
              cursor: isDragging ? 'grabbing' : 'grab'
            }"
            @dragstart.prevent
          />
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

export default {
  name: 'WorkTree',
  data() {
    return {
      scene: null,
      camera: null,
      renderer: null,
      controls: null,
      sphere: null,
      images: [],
      autoRotate: true,
      previewVisible: false,
      currentImage: {
        url: '',
        name: ''
      },
      raycaster: null,
      mouse: null,
      animationFrameId: null,
      scale: 1,
      rotation: 0,
      isDragging: false,
      lastX: 0,
      lastY: 0,
      translateX: 0,
      translateY: 0
    }
  },
  mounted() {
    this.initThree()
    this.loadImages()
    this.animate()
    
    // 初始化射线检测器和鼠标位置
    this.raycaster = new THREE.Raycaster()
    this.mouse = new THREE.Vector2()
    
    // 监听窗口大小变化和点击事件
    window.addEventListener('resize', this.onWindowResize)
    this.$refs.container.addEventListener('click', this.onMouseClick)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.onWindowResize)
    this.dispose()
  },
  methods: {
    initThree() {
      // 创建场景
      this.scene = new THREE.Scene()
      
      // 创建相机
      this.camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
      )
      this.camera.position.z = 30
      
      // 创建渲染器
      this.renderer = new THREE.WebGLRenderer({ antialias: true })
      this.renderer.setSize(window.innerWidth, window.innerHeight)
      this.renderer.setPixelRatio(window.devicePixelRatio)
      this.$refs.container.appendChild(this.renderer.domElement)
      
      // 添加控制器
      this.controls = new OrbitControls(this.camera, this.renderer.domElement)
      this.controls.enableDamping = true
      this.controls.dampingFactor = 0.05
      
      // 添加环境光
      const ambientLight = new THREE.AmbientLight(0xffffff, 0.5)
      this.scene.add(ambientLight)
      
      // 添加点光源
      const pointLight = new THREE.PointLight(0xffffff, 1)
      pointLight.position.set(10, 10, 10)
      this.scene.add(pointLight)
    },
    
    async loadImages() {
      const imageLoader = new THREE.TextureLoader()
      const radius = 15 // 球体半径
      
      // 从assets/worktree文件夹加载图片
      const images = require.context('../assets/worktree', false, /\.(jpg|jpeg|png)$/)
      const totalImages = images.keys().length
      
      console.log('加载的图片数量：', totalImages) // 添加调试日志
      
      images.keys().forEach((key, index) => {
        console.log('正在加载图片：', key) // 添加调试日志
        const texture = imageLoader.load(images(key))
        const material = new THREE.MeshBasicMaterial({
          map: texture,
          side: THREE.DoubleSide
        })
        
        // 增大图片尺寸
        const geometry = new THREE.PlaneGeometry(6, 4.5)
        const mesh = new THREE.Mesh(geometry, material)
        
        // 计算球面上的位置
        const phi = Math.acos(-1 + (2 * index) / totalImages)
        const theta = Math.sqrt(totalImages * Math.PI) * phi
        
        // 设置图片位置
        mesh.position.setFromSphericalCoords(
          radius,
          phi,
          theta
        )
        
        // 使图片始终面向球心
        mesh.lookAt(new THREE.Vector3(0, 0, 0))
        
        // 存储图片URL用于预览
        mesh.userData = {
          imageUrl: images(key),
          imageName: key.replace('./', '').replace(/\.(jpg|jpeg|png)$/, '')
        }
        
        this.scene.add(mesh)
        this.images.push(mesh)
      })
    },
    
    onMouseClick(event) {
      // 计算鼠标位置
      const rect = this.renderer.domElement.getBoundingClientRect()
      this.mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1
      this.mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1
      
      // 更新射线
      this.raycaster.setFromCamera(this.mouse, this.camera)
      
      // 检测相交的对象
      const intersects = this.raycaster.intersectObjects(this.images, true) // 添加 true 参数
      
      if (intersects.length > 0) {
        console.log('图片被点击', intersects[0].object.userData) // 添加调试日志
        const selectedMesh = intersects[0].object
        if (selectedMesh.userData && selectedMesh.userData.imageUrl) {
          this.showPreview(selectedMesh.userData.imageUrl, selectedMesh.userData.imageName)
        }
      }
    },
    
    showPreview(imageUrl, imageName) {
      this.currentImage = {
        url: imageUrl,
        name: imageName
      }
      this.previewVisible = true
      this.autoRotate = false
      this.resetPreview()
    },
    
    handleClosePreview() {
      this.previewVisible = false
      this.currentImage = { url: '', name: '' }
      this.resetPreview()
    },
    
    resetPreview() {
      this.scale = 1
      this.rotation = 0
      this.translateX = 0
      this.translateY = 0
    },
    
    handleZoomIn() {
      this.scale = Math.min(this.scale * 1.2, 5)
    },
    
    handleZoomOut() {
      this.scale = Math.max(this.scale / 1.2, 0.1)
    },
    
    handleRotateLeft() {
      this.rotation = (this.rotation - 90) % 360
    },
    
    handleRotateRight() {
      this.rotation = (this.rotation + 90) % 360
    },
    
    handleReset() {
      this.resetPreview()
    },
    
    handleWheel(e) {
      e.preventDefault()
      if (e.deltaY < 0) {
        this.handleZoomIn()
      } else {
        this.handleZoomOut()
      }
    },
    
    handleMouseDown(e) {
      this.isDragging = true
      this.lastX = e.clientX
      this.lastY = e.clientY
    },
    
    handleMouseMove(e) {
      if (!this.isDragging) return
      
      const deltaX = e.clientX - this.lastX
      const deltaY = e.clientY - this.lastY
      
      this.translateX += deltaX
      this.translateY += deltaY
      
      this.lastX = e.clientX
      this.lastY = e.clientY
    },
    
    handleMouseUp() {
      this.isDragging = false
    },
    
    animate() {
      // 存储动画帧ID
      this.animationFrameId = requestAnimationFrame(this.animate)
      
      if (this.autoRotate && this.scene) {  // 添加scene存在性检查
        this.scene.rotation.y += 0.001
      }
      
      if (this.controls) {  // 添加controls存在性检查
        this.controls.update()
      }
      
      if (this.renderer && this.scene && this.camera) {  // 添加所有必要对象的存在性检查
        this.renderer.render(this.scene, this.camera)
      }
    },
    
    onWindowResize() {
      this.camera.aspect = window.innerWidth / window.innerHeight
      this.camera.updateProjectionMatrix()
      this.renderer.setSize(window.innerWidth, window.innerHeight)
    },
    
    dispose() {
      // 取消动画帧
      if (this.animationFrameId) {
        cancelAnimationFrame(this.animationFrameId)
        this.animationFrameId = null
      }
      
      // 移除事件监听器
      if (this.$refs.container) {
        this.$refs.container.removeEventListener('click', this.onMouseClick)
      }
      
      // 销毁Three.js对象
      if (this.scene) {
        this.scene.traverse((object) => {
          if (object.geometry) {
            object.geometry.dispose()
          }
          if (object.material) {
            if (object.material.map) {
              object.material.map.dispose()
            }
            object.material.dispose()
          }
        })
      }
      
      if (this.renderer) {
        this.renderer.dispose()
      }
      
      if (this.controls) {
        this.controls.dispose()
      }
      
      // 清空引用
      this.scene = null
      this.camera = null
      this.renderer = null
      this.controls = null
      this.images = []
    }
  }
}
</script>

<style scoped>
.work-tree {
  width: 100%;
  height: 100vh;
  position: relative;
  overflow: hidden;
  background: #000;
}

.canvas-container {
  width: 100%;
  height: 100%;
}

.controls {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
}

.el-button {
  background: rgba(255, 255, 255, 0.2);
  color: white;
  border: 1px solid rgba(255, 255, 255, 0.3);
}

.el-button:hover {
  background: rgba(255, 255, 255, 0.3);
  color: white;
}

/* 预览对话框样式 */
:deep(.preview-dialog) {
  .el-dialog__header {
    background: #242424;
    padding: 15px 20px;
    margin: 0;
    
    .el-dialog__title {
      color: white;
    }
    
    .el-dialog__headerbtn .el-dialog__close {
      color: white;
    }
  }
  
  .el-dialog__body {
    padding: 0;
    height: calc(100vh - 120px);
  }
}

.preview-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #1a1a1a;
}

.preview-toolbar {
  padding: 16px;
  text-align: center;
  background: #242424;
  border-bottom: 1px solid #333;
}

.preview-toolbar .el-button-group {
  margin: 0 8px;
}

.preview-wrapper {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  position: relative;
}

.preview-image {
  max-width: 100%;
  max-height: calc(100vh - 180px);
  object-fit: contain;
  transition: transform 0.3s ease;
  transform-origin: center center;
  user-select: none;
  will-change: transform; /* 优化性能 */
}

.el-button {
  margin: 0 4px;
}

/* 暗色主题按钮样式 */
.preview-toolbar .el-button {
  background: #333;
  border-color: #444;
  color: #fff;
}

.preview-toolbar .el-button:hover {
  background: #444;
  border-color: #555;
}

.preview-toolbar .el-button:active {
  background: #222;
}
</style> 